//! @Author: DengLibin
//! @Date: Create in 2024-07-17 15:32:19
//! @Description:

use std::{collections::HashMap, sync::Arc};

use axum::{
    extract::Query,
    routing::{get, post},
    Extension, Json, Router,
};
use bcrypt::hash;
use chrono::Local;
use log::info;
use my_trait::{MustHaveFieldType, Struct2Map};
use serde_json::{json, Value};
use snowflaker::generator::Generator;

use crate::{
    app::AppState,
    entity::user::User,
    service::{self, user_service},
    sys::global::to_global_result,
    web::Resdata,
};

pub async fn route(router: Router) -> Router {
    //get查询参数
    let router = router.route("/user/user_page", get(user_page));
    let router = router.route("/user/post_user", post(post_user));
    let router = router.route("/user/user_fields", get(user_fields));
    let router = router.route("/user/get_user", get(get_user));
    let router = router.route("/user/delete", get(delete));
    let router = router.route("/user/update", post(update_user));
    let router = router.route("/user/filed_type", get(user_filed_types));
    let router = router.route("/user/insert_user", post(insert_user));

    router
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-17 15:48:53
/// @Description: 分页查询
pub async fn user_page(
    Extension(state): Extension<Arc<AppState>>,
    params: Query<HashMap<String, String>>,
) -> Json<Value> {
    let pool = &state.pool;
    let mut page: i32 = -1;
    let mut size: i32 = -1;
    let page_o = params.get("page");
    if let Some(page_s) = page_o {
        if let Ok(p) = page_s.parse::<i32>() {
            page = p;
        }
    }

    let size_o = params.get("size");
    if let Some(size_s) = size_o {
        if let Ok(s) = size_s.parse::<i32>() {
            size = s;
        }
    }
    if page == -1 || size == -1 {
        let o = json!(Resdata::<bool>::err("page 或 size 不能为空".into()));
        return Json(o);
    }

    let r = service::query_page::<User>(page, size, pool).await;
    Json(json!(Resdata::ok_result(r)))
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-17 18:42:24
/// @Description: 提交用户
pub async fn post_user(Json(user): Json<User>) -> Json<Value> {
    let map = user.to_map();
    Json(json!(map))
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-17 18:42:24
/// @Description: 添加用户
pub async fn insert_user(
    Extension(state): Extension<Arc<AppState>>,
    Json(mut user): Json<User>,
) -> Json<Value> {
    info!("time1:{}", my_util_lib::date::get_sys_timestamp_millis());
    let r = to_global_result(state.snowflaker.next_id());
    info!("time2:{}", my_util_lib::date::get_sys_timestamp_millis());
    //使用本地时间转Utc格式
    let now = Local::now().naive_local();
    match r {
        Ok(id) => {
            user.id = id as i64;
            user.create_time = Some(now.clone());
            user.update_time = Some(now);
            user.create_by = Some(0);
            user.update_by = Some(0);
            user.creator = Some(0);
            user.status = Some(1);
            user.deleted = Some(false);
            user.login_failed_count = Some(0);
            let r = to_global_result(hash("123456", 4));
            info!("time3:{}", my_util_lib::date::get_sys_timestamp_millis());
            if let Ok(password) = r {
                user.passwords = Some(password);
            } else {
                return Json(json!(Resdata::<String>::ok_result(r)));
            }

            let r = user_service::insert_user(user, &state.pool).await;
            Json(json!(Resdata::<User>::ok_result(r)))
        }
        Err(e) => Json(json!(Resdata::<()>::err(e.to_string()))),
    }
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-17 18:42:24
/// @Description: 提交用户
pub async fn update_user(
    Extension(state): Extension<Arc<AppState>>,
    Json(user): Json<User>,
) -> Json<Value> {
    let old = service::get_by_id::<User>(user.id, &state.pool).await;
    match old {
        Ok(old_o) => {
            if let Some(mut old_user) = old_o {
                //只更新这几个字段
                old_user.update_time = Some(Local::now().naive_local());
                old_user.create_time = user.create_time;
                old_user.name = user.name;
                old_user.update_by = Some(0);

                let r = service::update_one::<User>(user.id.into(), old_user, &state.pool).await;

                return Json(json!(Resdata::<()>::ok_result(r)));
            } else {
                return Json(json!(Resdata::<String>::err("记录不存在".into())));
            }
        }
        Err(err) => {
            return Json(json!(Resdata::<String>::err(err.to_string())));
        }
    }
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-18 14:07:04
/// @Description: 获取结构体字段
pub async fn user_fields() -> Json<Value> {
    let fields = User::get_field_names();
    Json(json!(fields))
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-19 11:44:11
/// @Description: 字段类型
pub async fn user_filed_types() -> Json<Value> {
    let field_types = User::field_types_map();
    Json(json!(field_types))
}

/// @Author: DengLibin
/// @Date: Create in 2024-07-18 16:15:08
/// @Description: 根据id查询
pub async fn get_user(
    Extension(state): Extension<Arc<AppState>>,
    params: Query<HashMap<String, String>>,
) -> Json<Resdata<Option<User>>> {
    let pool = &state.pool;
    let id_o = params.get("id");
    if let Some(id) = id_o {
        let id_r = id.parse::<i64>();
        if let Ok(id) = id_r {
            let r = service::get_by_id::<User>(id, pool).await;
            let res = Resdata::<Option<User>>::ok_result(r);
            Json(res)
        } else {
            Json(Resdata::<Option<User>>::err("id 错误".into()))
        }
    } else {
        return Json(Resdata::<Option<User>>::err("id 不能为空".into()));
    }
}
/// @Author: DengLibin
/// @Date: Create in 2024-07-18 16:44:19
/// @Description: 根据id删除
pub async fn delete(
    Extension(state): Extension<Arc<AppState>>,
    params: Query<HashMap<String, String>>,
) -> Json<Resdata<()>> {
    let pool = &state.pool;
    let id_o = params.get("id");
    if let Some(id) = id_o {
        let id_r = id.parse::<i64>();
        if let Ok(id) = id_r {
            let r = service::delete_by_id::<User>(id, pool).await;
            let res = Resdata::<()>::ok_result(r);
            Json(res)
        } else {
            Json(Resdata::<()>::err("id 错误".into()))
        }
    } else {
        return Json(Resdata::<()>::err("id 不能为空".into()));
    }
}
